home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / Tools / freeWAIS-sf-1.1 / ir / transprt.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-05-19  |  12.0 KB  |  481 lines

  1. /* WIDE AREA INFORMATION SERVER SOFTWARE:
  2.    No guarantees or restrictions.  See the readme file for the full standard
  3.    disclaimer.
  4. */
  5.  
  6. /* Copyright (c) CNIDR (see ../COPYRIGHT) */
  7.  
  8.  
  9. #ifndef lint
  10. static char *RCSid = "$Header: /usr/local/ls6/src+data/src/freeWAIS-0.2-sf/ir/RCS/transprt.c,v 1.2 1994/03/08 21:07:02 pfeifer Exp $";
  11. #endif
  12.  
  13. /* this is a krufty transport layer for comm mediums that can not handle
  14.  * all 8 bits of ascii.
  15.  * Written by Harry Morris, modified by brewster.
  16.  * Hexcode written by Steve Swartz
  17.  * 
  18.  */
  19.  
  20. /* to do
  21.  *
  22.  *  compression
  23.  *  encryption
  24.  */
  25.  
  26. /* Change log:
  27.  * $Log: transprt.c,v $
  28.  * Revision 1.2  1994/03/08  21:07:02  pfeifer
  29.  * Patchlevel 04
  30.  *
  31.  * Revision 1.1  1993/02/16  15:05:35  freewais
  32.  * Initial revision
  33.  *
  34.  * Revision 1.2  92/02/12  13:51:34  jonathan
  35.  * Added "$Log" so RCS will put the log message in the header
  36.  * 
  37.  * 
  38.  * 7/7/90 -brewster
  39.  * merged arts and harry's changes 7/7/90 -brewster
  40.  *
  41.  * 11/6/90 -tracy
  42.  * shift 6 bytes starting from [ as IBM gateway program
  43.  * masks out characters [\]^` in input,
  44.  * append H and I to the function names corresponding to the
  45.  * oroginal coding and the modified one. 'I' indicates IBM. 
  46.  */
  47.  
  48. #include "transprt.h"
  49. #include "wmessage.h" 
  50. #include "ustubs.h"
  51.  
  52. /*---------------------------------------------------------------------*/
  53. static char alphaH[] = /* Must be 65 consecutive ascii characters */
  54.   "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnop";
  55.  
  56.  
  57. /*---------------------------------------------------------------------*/
  58.  
  59. static void hexCodeH _AP((char* data,long* len));
  60.  
  61. static void
  62. hexCodeH(data,len)
  63. char* data;
  64. long* len;
  65. /* compose a message for sending over ascii terminal lines. Input is '*len'
  66.  * binary bytes; output is 'ceiling(*len/3) * 4' characters from alpha[].
  67.  *
  68.  * Encoding goes like this. Let capital letters represent bits:
  69.  * Input bytes:  ABCDEFGH IJKLMNOP QRSTUVWX
  70.  * Output chars: alpha[CDEFGH] alpha[ABIJKL] alpha[QRMNOP] alpha[SRUVWX]
  71.  *
  72.  * 1 byte at end: ABCDEFGH
  73.  * Output chars:  alpha[CDEFGH] alpha[AB0000] alpha[1000000] alpha [1000000]
  74.  *
  75.  * 2 bytes at end: ABCDEFGH IJKLMNOP
  76.  * Output chars:   alpha[CDEFGH] alpha[ABIJKL] alpha[00MNOP] alpha [1000000]
  77.  */
  78. {
  79.   long i, j;
  80.   
  81.   switch (*len % 3)
  82.     {
  83.     case 2:
  84.       i = *len; j = (*len+1)/3 * 4 - 1; *len = j + 1;
  85.       data[j]   = alphaH[64];
  86.       data[j-1] = alphaH[data[i-1] & 0x0f];
  87.       data[j-2] = alphaH[(data[i-2] & 0xc0) >> 2 | (data[i-1] & 0xf0) >> 4];
  88.       data[j-3] = alphaH[data[i-2] & 0x3F];
  89.       break;
  90.     case 1:
  91.       i = *len + 1; j = (*len+2)/3 * 4 - 1; *len = j + 1;
  92.       data[j]   = alphaH[64];
  93.       data[j-1] = alphaH[64];
  94.       data[j-2] = alphaH[(data[i-2] & 0xc0) >> 2];
  95.       data[j-3] = alphaH[data[i-2] & 0x3F];
  96.       break;
  97.     default:
  98.       i = *len + 2; j = (*len)/3 * 4 + 3; *len = j - 3;
  99.       break;
  100.     }
  101.   
  102.   for (i -= 3, j -= 4; i > 0; i -= 3, j -= 4)
  103.     { 
  104.       data[j]   = alphaH[data[i] & 0x3F];
  105.       data[j-1] = alphaH[(data[i] & 0xc0) >> 2 | (data[i-1] & 0x0f)];
  106.       data[j-2] = alphaH[(data[i-2] & 0xc0) >> 2 | (data[i-1] & 0xf0) >> 4];
  107.       data[j-3] = alphaH[data[i-2] & 0x3F];
  108.     }
  109. }
  110.  
  111. /*---------------------------------------------------------------------*/
  112.  
  113. static void hexDecodeH _AP((char* data,long* len));
  114.  
  115. static void
  116. hexDecodeH(data,len)
  117. char* data;
  118. long* len;
  119. /* Incoming data is 'len' letters from alpha[] created by hexCode(). 'len'
  120.  *  will always be divisble by 4. Output is the binary bytes that were 
  121.  *  encoded into 'data'.
  122.  *
  123.  * If alpha[] isn't consecutive ascii characters, then the function moving 
  124.  *  from ascii data to the 'bX' values has to become more complicated than
  125.  *  data[] - alpha[0].
  126.  */
  127. {
  128.   unsigned char b0, b1, b2, b3;
  129.   long i, j;
  130.  
  131.   
  132.   for (i = 3, j = 4; j < *len; i += 3, j += 4)
  133.     {
  134.       b0 = (data[j-4] & 0x07F) - alphaH[0];
  135.       b1 = (data[j-3] & 0x07F) - alphaH[0];
  136.       b2 = (data[j-2] & 0x07F) - alphaH[0];
  137.       b3 = (data[j-1] & 0x07F) - alphaH[0];
  138.       data[i-3] = b0 | (b1 & 0x30) << 2;
  139.       data[i-2] = (b1 & 0x0f) << 4 | (b2 & 0x0f);
  140.       data[i-1] = b3 | (b2 & 0x30) << 2;
  141.     }
  142.  
  143.   *len = *len/4 * 3 - 2;
  144.   b0 = (data[j-4] & 0x07F) - alphaH[0];
  145.   b1 = (data[j-3] & 0x07F) - alphaH[0];
  146.   b2 = (data[j-2] & 0x07F) - alphaH[0];
  147.   b3 = (data[j-1] & 0x07F) - alphaH[0];
  148.   data[i-3] = b0 | (b1 & 0x30) << 2;
  149.  
  150.   if (b2 != 64)    
  151.     {
  152.       data[i-2] = (b1 & 0x0f) << 4 | (b2 & 0x0f);
  153.       (*len)++;
  154.     }
  155.  
  156.   if (b3 != 64)
  157.     {
  158.       data[i-1] = b3 | (b2 & 0x30) << 2;
  159.       (*len)++;
  160.     }
  161. }
  162.  
  163. /*---------------------------------------------------------------------*/
  164.  
  165. void
  166. transportCodeH(data,len)
  167. char* data;
  168. long* len;
  169. /* krufty serial line transport layer - encode in hex and append in cr */
  170. /* Now it also writes a wais packet header on to the front of the packet.
  171.  *   --art 
  172.  */
  173.   hexCodeH(data,len);
  174.   data[*len] = '\r';
  175.   data[*len + 1] = '\0';
  176.   *len += 1;
  177. }
  178.  
  179. /*---------------------------------------------------------------------*/
  180.  
  181. void
  182. transportDecodeH(data,len)
  183. char* data;
  184. long* len;
  185. /* decode above */
  186. /* This does not have to deal with the wais packet header since it has
  187.    been removed at the end of the read.  */
  188.   if (*len == 0)
  189.     return;
  190.     
  191.   *len -= 1;
  192.   hexDecodeH(data,len);
  193. }
  194.  
  195. /*---------------------------------------------------------------------
  196.  Below are the set of transport coding/decoding functions for clients
  197.  dialing through IBM to DowQuest. Unlike the above one that
  198.  uses 65 consecutive ASCII character for the coding/decoding table,
  199.  table entries after charcater 'Z' are shift 6 characters.
  200.  *--------------------------------------------------------------------*/ 
  201.  
  202. #define LAST_NON_SHIFT_CHAR 90
  203. #define SHIFT_OFFSET   6
  204.  
  205. static char alphaI[] = 
  206.   "0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv";
  207.  
  208.  
  209. static void hexCodeI _AP((char* data,long* len));
  210.  
  211. static void
  212. hexCodeI(data,len)
  213. char* data;
  214. long* len;
  215. /* compose a message for sending over ascii terminal lines. Input is '*len'
  216.  * binary bytes; output is 'ceiling(*len/3) * 4' characters from alpha[].
  217.  *
  218.  * Encoding goes like this. Let capital letters represent bits:
  219.  * Input bytes:  ABCDEFGH IJKLMNOP QRSTUVWX
  220.  * Output chars: alpha[CDEFGH] alpha[ABIJKL] alpha[QRMNOP] alpha[SRUVWX]
  221.  *
  222.  * 1 byte at end: ABCDEFGH
  223.  * Output chars:  alpha[CDEFGH] alpha[AB0000] alpha[1000000] alpha [1000000]
  224.  *
  225.  * 2 bytes at end: ABCDEFGH IJKLMNOP
  226.  * Output chars:   alpha[CDEFGH] alpha[ABIJKL] alpha[00MNOP] alpha [1000000]
  227.  */
  228. {
  229.   long i, j;
  230.   
  231.   switch (*len % 3)
  232.     {
  233.     case 2:
  234.       i = *len; j = (*len+1)/3 * 4 - 1; *len = j + 1;
  235.       data[j]   = alphaI[64];
  236.       data[j-1] = alphaI[data[i-1] & 0x0f];
  237.       data[j-2] = alphaI[(data[i-2] & 0xc0) >> 2 | (data[i-1] & 0xf0) >> 4];
  238.       data[j-3] = alphaI[data[i-2] & 0x3F];
  239.       break;
  240.     case 1:
  241.       i = *len + 1; j = (*len+2)/3 * 4 - 1; *len = j + 1;
  242.       data[j]   = alphaI[64];
  243.       data[j-1] = alphaI[64];
  244.       data[j-2] = alphaI[(data[i-2] & 0xc0) >> 2];
  245.       data[j-3] = alphaI[data[i-2] & 0x3F];
  246.       break;
  247.     default:
  248.       i = *len + 2; j = (*len)/3 * 4 + 3; *len = j - 3;
  249.       break;
  250.     }
  251.   
  252.   for (i -= 3, j -= 4; i > 0; i -= 3, j -= 4)
  253.     { 
  254.       data[j]   = alphaI[data[i] & 0x3F];
  255.       data[j-1] = alphaI[(data[i] & 0xc0) >> 2 | (data[i-1] & 0x0f)];
  256.       data[j-2] = alphaI[(data[i-2] & 0xc0) >> 2 | (data[i-1] & 0xf0) >> 4];
  257.       data[j-3] = alphaI[data[i-2] & 0x3F];
  258.     }
  259. }
  260.  
  261. /*---------------------------------------------------------------------*/
  262.  
  263. static void hexDecodeI _AP((char* data,long * len));
  264.  
  265. static void
  266. hexDecodeI(data,len)
  267. char* data;
  268. long* len;
  269. /* Incoming data is 'len' letters from alpha[] created by hexCode(). 'len'
  270.  *  will always be divisble by 4. Output is the binary bytes that were 
  271.  *  encoded into 'data'.
  272.  *
  273.  * If alpha[] isn't consecutive ascii characters, then the function moving 
  274.  *  from ascii data to the 'bX' values has to become more complicated than
  275.  *  data[] - alpha[0].
  276.  */
  277. {
  278.   unsigned char b0, b1, b2, b3;
  279.   long i, j;
  280.  
  281.   for ( i=0; i < *len ; i++ )
  282.     if ( data[i] > LAST_NON_SHIFT_CHAR ) data[i] -= SHIFT_OFFSET;
  283.   
  284.   for (i = 3, j = 4; j < *len; i += 3, j += 4)
  285.     {
  286.       b0 = (data[j-4] & 0x07F) - alphaI[0];
  287.       b1 = (data[j-3] & 0x07F) - alphaI[0];
  288.       b2 = (data[j-2] & 0x07F) - alphaI[0];
  289.       b3 = (data[j-1] & 0x07F) - alphaI[0];
  290.       data[i-3] = b0 | (b1 & 0x30) << 2;
  291.       data[i-2] = (b1 & 0x0f) << 4 | (b2 & 0x0f);
  292.       data[i-1] = b3 | (b2 & 0x30) << 2;
  293.     }
  294.  
  295.   *len = *len/4 * 3 - 2;
  296.   b0 = (data[j-4] & 0x07F) - alphaI[0];
  297.   b1 = (data[j-3] & 0x07F) - alphaI[0];
  298.   b2 = (data[j-2] & 0x07F) - alphaI[0];
  299.   b3 = (data[j-1] & 0x07F) - alphaI[0];
  300.   data[i-3] = b0 | (b1 & 0x30) << 2;
  301.  
  302.   if (b2 != 64)    
  303.     {
  304.       data[i-2] = (b1 & 0x0f) << 4 | (b2 & 0x0f);
  305.       (*len)++;
  306.     }
  307.  
  308.   if (b3 != 64)
  309.     {
  310.       data[i-1] = b3 | (b2 & 0x30) << 2;
  311.       (*len)++;
  312.     }
  313. }
  314.  
  315. /*---------------------------------------------------------------------*/
  316.  
  317. void
  318. transportCodeI(data,len)
  319. char* data;
  320. long* len;
  321. /* krufty serial line transport layer - encode in hex and append in cr */
  322. /* Now it also writes a wais packet header on to the front of the packet.
  323.  *   --art 
  324.  */
  325.   hexCodeI(data,len);
  326.   data[*len] = '\r';
  327.   data[*len + 1] = '\0';
  328.   *len += 1;
  329. }
  330.  
  331. /*---------------------------------------------------------------------*/
  332.  
  333. void
  334. transportDecodeI(data,len)
  335. char* data;
  336. long* len;
  337. /* decode above */
  338. /* This does not have to deal with the wais packet header since it has
  339.    been removed at the end of the read.  */
  340.   if (*len == 0)
  341.     return;
  342.     
  343.   *len -= 1;
  344.   hexDecodeI(data,len);
  345. }
  346.  
  347. /*---------------------------------------------------------------------*/
  348.  
  349.  
  350. #ifdef NOTDEFINED /* here for back compatibility */
  351.  
  352. static void hexCode _AP((char* data,long * len));
  353.  
  354. static void
  355. hexCode(data,len)
  356. char* data;
  357. long* len;
  358. /* compose a message for sending over ascii terminal lines.  The data is hex,
  359.  */
  360. { long i;
  361.   for (i = *len-1; i >= 0; i--)
  362.     { data[i*2+1] = (data[i]&0x0F) + 'a';
  363.       data[i*2] = ((data[i]>>4)&0x0F) + 'a';
  364.     }
  365.   data[*len*2] = '\0';
  366.   *len = *len * 2;
  367. }
  368.  
  369. /*---------------------------------------------------------------------------*/
  370.  
  371. static void hexDecode _AP((char* data,long * len));
  372.  
  373. static void
  374. hexDecode(data,len)
  375. char* data;
  376. long* len;
  377. /* converts a buffer full of dataLen bytes of hex in place into the
  378. equivalent binary form. len is filled with the actual number of binary bytes.
  379.  */
  380. { long i;
  381.   *len = *len / 2;
  382.   for (i = 0; i < *len; i++)
  383.     { long temp = 0;
  384.       temp = (data[i*2]-'a')<<4;
  385.       temp += data[i*2+1]-'a';
  386.       data[i] = (char)temp;
  387.     }
  388.   data[*len] = '\0';
  389. }
  390.  
  391. #endif /* def NOTDEFINED */
  392. /*---------------------------------------------------------------------------*/
  393.  
  394. boolean
  395. transportCode(encoding,data,len)
  396. long encoding;
  397. char* data;
  398. long* len;
  399. /* krufty serial line transport layer - encode in hex and add trailing nl */
  400. {
  401.   switch (encoding){
  402.   case NO_ENCODING:
  403.     /* do nothing */
  404.     return(true);
  405.   case HEX_ENCODING:
  406.     transportCodeH(data,len);
  407.     return(true);
  408.   case IBM_HEXCODING:
  409.     transportCodeI(data,len);
  410.     return(true);
  411.   default:
  412.     return(false);
  413.   }
  414. }
  415.  
  416. /*---------------------------------------------------------------------------*/
  417.  
  418. boolean
  419. transportDecode(encoding,data,len)
  420. long encoding;
  421. char* data;
  422. long* len;
  423. /* decode above */
  424. {
  425.   switch (encoding){
  426.   case NO_ENCODING:
  427.     /* do nothing */
  428.     return(true);
  429.   case HEX_ENCODING:
  430.     transportDecodeH(data,len);
  431.     return(true);
  432.   case IBM_HEXCODING:
  433.     transportDecodeI(data,len);
  434.     return(true);
  435.   default:
  436.     return(false);
  437.   }
  438. }
  439.  
  440. /*---------------------------------------------------------------------------*/
  441.  
  442.  
  443.  
  444.  
  445.  
  446.  
  447. #ifdef old /* from the bad old days */
  448.  
  449.  
  450. /*---------------------------------------------------------------------------*/
  451.  
  452. void
  453. transportCode(data,len)
  454. char* data;
  455. long* len;
  456. /* krufty serial line transport layer - encode in hex and add trailing nl */
  457. {
  458.   hexCode(data,len);
  459.   data[*len] = '\r';
  460.   data[*len+1] = '\0';
  461. }
  462.  
  463. /*---------------------------------------------------------------------------*/
  464.  
  465. void
  466. transportDecode(data,len)
  467. char* data;
  468. long* len;
  469. /* decode above */
  470. {
  471.   hexDecode(data,len);
  472. }
  473.  
  474. /*---------------------------------------------------------------------------*/
  475.  
  476. #endif /* old */
  477.